/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.elem;

import java.awt.*;
import java.io.*;
import java.util.*;

import org.w3c.dom.*;

import self.awt.*;
import self.awt.painter.*;
import self.gee.*;
import self.lang.*;
import self.xml.*;

public class ContextMenuView extends ARectangularHandledElement {
	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
  final static public String ITEMS_PROP = "items";
  final static public String DEFAULT_CTX_MENU =
                                                  "Undo       Ctrl+Z\n" +
                                                  "Redo       Shift+Ctrl+Z\n" +
                                                  "-\n" +
                                                  "Cut        Ctrl+X\n" +
                                                  "Copy       Ctrl+C\n" +
                                                  "Paste      Ctrl+V\n" +
                                                  "Delete\n" +
                                                  "-\n" +
                                                  "Select All Ctrl+A\n";
  
  final static private Font menuItemFont = new Font( "DialogInput", Font.PLAIN, 12 );
  
  private String  menuItems = DEFAULT_CTX_MENU;
  
  transient protected MenuPaintContext   menuContext = new MenuPaintContext();
  
  protected           TextPainter         textPainter;
  
  public ContextMenuView() {
    fig.setBounds( 10, 10, 165, 125 );
    menuContext.parseSeperatorLines();
//    PainterManager.registerOwner( this );
//    textPainter = (TextPainter) PainterManager.getPainterForOwner( this, TextPainter.class );
  }
  
  public void       setLayer( IDiagramLayer layerToDrawOn, boolean add ) {
    super.setLayer( layerToDrawOn, add );
    textPainter = (TextPainter) PainterManager.getPainterForOwner( layer, TextPainter.class );
  }
  
  // IEditableElement support
  public void       getProperties( Map store ) {
    store.put( ITEMS_PROP, menuItems );
  }
  
  public void       setProperties( Map data ) {
    menuItems = (String) data.get( ITEMS_PROP );
    resetFrame();
    menuContext.parseSeperatorLines();
    layer.setDirty();
  }
  
  // IPersistentElement support  
  public void readFrom( Node self, HashMap idObjLookUp ) throws DOMException {
    super.readFrom( self, idObjLookUp );
    menuItems = DomUtils.getElementText( self );
    menuContext.parseSeperatorLines();
    resetFrame();
  }
  
  public void writeTo( Document doc, Element self, HashMap objIdLookup ) throws DOMException {
    super.writeTo( doc, self, objIdLookup );
    DomUtils.setElementText( self, StringUtils.toEmptyIfNull(menuItems) );
  }  
  
  public void       paint( Graphics surface ) {
    if ( outlineOnly ) {
      surface.setColor(frameColor);
      surface.drawRect( fig.x, fig.y, fig.width, fig.height );
      return;
    }

    surface.setColor( Color.lightGray );
    surface.fillRect( fig.x, fig.y, fig.width, fig.height );

    surface.setColor(frameColor);
    surface.drawRect( fig.x, fig.y, fig.width, fig.height );
    
    surface.drawRect( fig.x, fig.y, fig.width, fig.height );
    paintMenu( surface );
  }
  
  private void paintMenu( Graphics surface ) {
    menuContext.resetForPaint();
    int endXPos = fig.x + fig.width;
    int endYPos = fig.y + fig.height;
    int max = menuContext.getIterationCount();
    int startAt = fig.y + 2;
    for ( int cntr = 0; cntr < max; cntr++ ) {
      if ( startAt >= endYPos )
        break;
      if ( cntr > 0 )
        surface.drawLine( fig.x, startAt, endXPos, startAt );
      menuContext.setPaintIteration( cntr, startAt );
      startAt = textPainter.paint( surface, menuContext, false );
      if ( !textPainter.didWriteAll() )
        break;
    }
  }

  protected void resetFrame() {
	// nothing to do.
  }
  
  protected class MenuPaintContext extends ATextRenderInfoAdapter {
    private String    content;
    private Rectangle bounds = new Rectangle();
    private java.util.List  menuGroups = new ArrayList();
    
    public MenuPaintContext() {
      format = ITextRenderInfo.TRIM_FORMAT;
    }
    
    public void resetForPaint() {
      bounds.setBounds( fig );
      bounds.grow( -2, -2 );
    }
    
    public void setPaintIteration( int cntr, int startAt ) {
      content = (String) menuGroups.get( cntr );
      bounds.height -= startAt - bounds.y;
      bounds.y = startAt;
    }
    
    public int getIterationCount() {
      return menuGroups.size();
    }
    
    public void parseSeperatorLines() {
      menuGroups.clear();  
      StringReader sgr = new StringReader( menuItems );
      BufferedReader br = new BufferedReader( sgr );
      String line;
      StringBuffer group = new StringBuffer();
      try {
        while ( (line = br.readLine()) != null ) {
          if ( line.equals("-") ) {
            menuGroups.add( group.toString() );
            group.setLength( 0 );
          } else
            group.append( line + "\n" );
        }
        menuGroups.add( group.toString() );
      } catch ( IOException err ) {
    	// nothing to do.
      }
    }
    
    public String     getText() {
      return content;
    }
    
    public Rectangle  getBounds() {
      return bounds;
    }
    
    public Font       getFont() {
      return menuItemFont;
    }
    
    public Color      getColor() {
      return frameColor;
    }
  }
}